"use strict";

window.$ = function(id) {
    return id ? document.getElementById(id) : [];
};

window.$.nm = function(elname) {
    return document.getElementsByName(elname);
};

window.$.all = function(selector) {
    return document.querySelectorAll(selector);
};

window.$.empty = function(id) {
    var element = "string" == typeof id ? document.getElementById(id) : id;
    if (element) for (;element.hasChildNodes(); ) element.removeChild(element.firstChild);
};

window.$.debounce = function(func, wait, immediate) {
    var timeout;
    return function() {
        var context = this, args = arguments, callNow = immediate && !timeout;
        clearTimeout(timeout);
        timeout = setTimeout(function() {
            timeout = null;
            immediate || func.apply(context, args);
        }, wait);
        callNow && func.apply(context, args);
    };
};

window.$.domainFromURL = function(website) {
    return website = website.toLowerCase().replace(/^https?:\/\//, "").replace(/\/.*$/, "").replace(/:.*$/, "");
};

window.$.__defineGetter__("version", function() {
    return "20210305";
});

window.$.__defineGetter__("browserSlug", function() {
    return "chrome";
});

window.$.__defineGetter__("storeUrl", function() {
    return "https://chrome.google.com/webstore/";
});

window.$.__defineGetter__("shortcutsUrl", function() {
    return "chrome://extensions/shortcuts";
});

window.$.__defineGetter__("extensionVersion", function() {
    return chrome.runtime.getManifest().version;
});

window.$.__defineGetter__("canCloseWindow", function() {
    return !0;
});

window.$.closeSelf = function() {
    window.close();
};

window.$.extractLastErrorMessage = function(error) {
    return "object" == typeof error && 1 === Object.keys(error).length && Object.prototype.hasOwnProperty.call(error, "message") ? error.message : error;
};

window.$.logLastError = function(category, error) {
    var errorMessage = window.$.extractLastErrorMessage(error);
    [ "Could not establish connection. Receiving end does not exist.", "The browser is shutting down.", "The extensions gallery cannot be scripted.", "The frame was removed.", "The tab was closed.", "This page cannot be scripted due to an ExtensionsSettings policy.", "Unknown error." ].includes(errorMessage) || 0 === errorMessage.indexOf("No tab with id:") || 0 === errorMessage.indexOf("Cannot access ") ? window.console.log(category, error) : window.console.error(category, error);
};

window.$.verCompare = function(a, b) {
    for (var na, nb, pa = a.split("."), pb = b.split("."), i = 0; i < 3; i++) {
        na = Number(pa[i]);
        if ((nb = Number(pb[i])) < na) return 1;
        if (na < nb) return -1;
        if (!isNaN(na) && isNaN(nb)) return 1;
        if (isNaN(na) && !isNaN(nb)) return -1;
    }
    return 0;
};

window.$.__defineGetter__("isBrowserSupported", function() {
    return "getBackgroundPage" in chrome.runtime && "storage" in chrome && "local" in chrome.storage;
});

window.$.__defineGetter__("background", function() {
    return chrome.extension.getBackgroundPage();
});

window.$.getBackgroundAsync = function(callback) {
    chrome.runtime.getBackgroundPage(callback);
};

window.$.__defineGetter__("popup", function() {
    var popup = chrome.extension.getViews({
        type: "popup"
    });
    return 0 < popup.length ? popup[0] : null;
});

window.$.setDefaultPopup = function() {
    chrome.browserAction.setPopup({
        popup: "popup.html"
    }, function() {
        chrome.runtime.lastError && window.$.logLastError("setDefaultPopup", chrome.runtime.lastError);
    });
};

window.$.runtime = {
    onMessageListener: function(callback) {
        chrome.runtime.onMessage.addListener(callback);
    }
};

window.$.tab = {
    open: function(url) {
        chrome.tabs.create({
            url: url
        });
    }
};

window.$.tabs = {
    sendMessage: function(tabId, message, callbackReload) {
        chrome.tabs.sendMessage(tabId, message, null, function() {
            if (chrome.runtime.lastError) {
                var errorMessage = window.$.extractLastErrorMessage(chrome.runtime.lastError);
                if ("Could not establish connection. Receiving end does not exist." === errorMessage || "The message port closed before a response was received." === errorMessage || "The message port closed before a reponse was received." === errorMessage) {
                    window.console.log("tabs.sendMessage", errorMessage);
                    callbackReload && callbackReload(tabId);
                } else window.$.logLastError("tabs.sendMessage", errorMessage);
            }
        });
    },
    query: function(queryInfo, callback) {
        chrome.tabs.query(queryInfo, callback);
    }
};

window.$.commandEvent = function(callback) {
    chrome.commands.onCommand.addListener(callback);
};

window.$.setIcon = function(details) {
    details.icon && chrome.browserAction.setIcon({
        path: details.icon,
        tabId: details.tabId
    }, function() {
        chrome.runtime.lastError && window.$.logLastError("setIcon:setIcon", chrome.runtime.lastError);
    });
    details.title && chrome.browserAction.setTitle({
        title: details.title,
        tabId: details.tabId
    }, function() {
        chrome.runtime.lastError && window.$.logLastError("setIcon:setTitle", chrome.runtime.lastError);
    });
};

window.$.icon = {};

window.$.icon.__defineSetter__("title", function(value) {
    chrome.browserAction.setTitle({
        title: value
    }, function() {
        chrome.runtime.lastError && window.$.logLastError("icon.title", chrome.runtime.lastError);
    });
});

window.$.icon.__defineSetter__("path", function(value) {
    chrome.browserAction.setIcon({
        path: value
    }, function() {
        chrome.runtime.lastError && window.$.logLastError("icon.path", chrome.runtime.lastError);
    });
});

window.$.icon.badge = {};

window.$.icon.badge.__defineSetter__("text", function(value) {
    chrome.browserAction.setBadgeText({
        text: value
    }, function() {
        chrome.runtime.lastError && window.$.logLastError("icon.badge.text", chrome.runtime.lastError);
    });
});

window.$.icon.badge.__defineSetter__("backgroundColor", function(value) {
    chrome.browserAction.setBadgeBackgroundColor({
        color: value
    }, function() {
        chrome.runtime.lastError && window.$.logLastError("icon.badge.backgroundColor", chrome.runtime.lastError);
    });
});

window.$.storage = {};

window.$.storage.get = function(type, keys, onGot, onError) {
    chrome.storage[type].get(keys, function(data) {
        chrome.runtime.lastError ? onError && onError(window.$.extractLastErrorMessage(chrome.runtime.lastError)) : onGot(data);
    });
};

window.$.storage.set = function(type, keys, onSet, onError) {
    chrome.storage[type].set(keys, function() {
        chrome.runtime.lastError ? onError && onError(window.$.extractLastErrorMessage(chrome.runtime.lastError)) : onSet && onSet();
    });
};

window.$.storage.onChangedListen = function(callback) {
    chrome.storage.onChanged.addListener(callback);
};

window.$.openOptionsPage = function() {
    chrome.runtime.openOptionsPage ? chrome.runtime.openOptionsPage() : chrome.tabs.create({
        url: "options.html"
    });
};

window.$.options = {};

window.$.options.getBoolean = function(value, defaultValue) {
    return "boolean" == typeof value ? value : defaultValue;
};

window.$.options.getObject = function(value, defaultValue) {
    return "object" == typeof value ? value : defaultValue;
};

window.$.options.getObjectIndividual = function(value, defaultValue) {
    if ("object" != typeof value) return defaultValue;
    var newValue = {};
    for (var item in defaultValue) newValue[item] = void 0 !== value[item] ? value[item] : defaultValue[item];
    return newValue;
};

window.$.options.loadCheckbox = function(storage, key) {
    "boolean" == typeof storage[key] && (window.$(key).checked = storage[key]);
};

window.$.options.loadInput = function(storage, key) {
    void 0 !== storage[key] && (window.$(key).value = storage[key]);
};

window.$.options.loadRadios = function(storage, key) {
    for (var radios = window.$.nm(key), storageValue = storage[key], i = 0; i < radios.length; i++) if (radios[i].value === storageValue) {
        radios[i].checked = !0;
        break;
    }
};

window.$.options.saveCheckbox = function(storage, key) {
    storage[key] = window.$(key).checked;
};

window.$.options.saveInput = function(storage, key) {
    storage[key] = window.$(key).value;
};

window.$.options.saveRadios = function(storage, key) {
    for (var radios = window.$.nm(key), i = 0; i < radios.length; i++) if (radios[i].checked) {
        storage[key] = radios[i].value;
        break;
    }
};